package com.base.service.impl;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.text.StrPool;
import cn.hutool.core.util.DesensitizedUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.crypto.digest.BCrypt;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.base.domain.SysDept;
import com.base.domain.SysDict;
import com.base.domain.SysUser;
import com.base.enums.DeletedEnum;
import com.base.enums.StatusEnum;
import com.base.mapper.SysUserMapper;
import com.base.mapper.SysUserRoleMapper;
import com.base.service.SysDeptService;
import com.base.service.SysDictService;
import com.base.service.SysUserService;
import com.base.utils.BeanUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Base64Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author gxd
 * @since 2025/6/6
 */
@Slf4j
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {

    @Autowired
    private SysUserMapper userMapper;

    @Autowired
    private SysUserRoleMapper userRoleMapper;

    @Autowired
    private SysDictService dictService;

    @Autowired
    private SysDeptService deptService;

    /**
     * 分页列表-用户列表
     * @param user 用户查询条件
     * @return 用户列表
     */
    @Override
    public List<SysUser> pageList(SysUser user) {
        List<SysUser> userList = userMapper.pageList(user);
        return userList.stream()
                .map(this::desensitizedData)
                .collect(Collectors.toList());
    }

    /**
     * 脱敏数据
     * @param user 用户信息
     * @return 用户信息
     */
    public SysUser desensitizedData(SysUser user) {
        if (ObjectUtil.isNull(user)) {
            return null;
        }

        // sysUser.setSexMc();
        // sysUser.setStatusMc();
        user.setNickName(DesensitizedUtil.chineseName(user.getNickName()));
        user.setIdcard(DesensitizedUtil.idCardNum(user.getIdcard(), 3, 4));
        user.setPhone(DesensitizedUtil.fixedPhone(user.getPhone()));
        user.setAvatar(Base64Util.encode(user.getAvatar()));
        user.setPassword(null);
        return user;
    }

    /**
     * 详情信息-根据Id获取用户详情信息
     * @param id 用户Id
     * @return 用户详情信息
     */
    @Override
    public SysUser getInfoById(Long id) {
        return desensitizedData(this.getById(id));
    }

    /**
     * 添加或修改-用户信息
     * @param user 用户实体
     * @return 用户信息
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public SysUser addOrEdit(SysUser user) {
        Assert.notNull(user, "用户信息不能为空");
        if (ObjectUtil.isNotNull(user.getId())) {
            SysUser userInfo = Assert.notNull(this.getById(user.getId()), "要修改的用户记录不存在");
            BeanUtils.copyNotEmptyProperties(user, userInfo);
            // 密码加密
            userInfo.setPassword(BCrypt.hashpw(user.getPassword()));
            this.updateById(userInfo);
            return userInfo;
        }

        user.setDeleted(DeletedEnum.NO.getCode());
        // 密码加密
        user.setPassword(BCrypt.hashpw(user.getPassword()));
        this.save(user);
        return user;
    }

    /**
     * 删除-用户信息（支持批量）
     * @param ids 用户Id（多个需逗号分隔）
     * @return 结果
     */
    @Override
    public int deleteByIds(String ids) {
        Assert.notEmpty(ids, "缺少必要参数：请提供要删除的记录Id");
        return userMapper.deleteBatchIds(Arrays.asList(ids.split(StrPool.COMMA)));
    }

    /**
     * 获取用户信息-带翻译（deptMc、sexMc）
     * @return 用户列表
     */
    @Override
    public List<SysUser> selectUserMcList(SysUser sysUser) {
        // 1、获取某个list为空会不会有问题？测试发现并不会 2、并行流会不会生效？生效，通过peek方法打印当前线程名，发现是多个，生效 3、使用并行流线程安全吗？ 安全
        // 4、使用并行流，出发点是提高查询效率，但是实际开发时通过分页控制，就不会一下大数据量了 5、并行在导出时超过5w考虑并行
        // 测试发现的bug：用户表的性别是Integer，字典表的值是String，需要转换
        // 获取全部用户信息
        List<SysUser> userList = userMapper.selectList(
                Wrappers.lambdaQuery(SysUser.class).eq(SysUser::getStatus, StatusEnum.OK.getCode()).eq(SysUser::getDeleted, DeletedEnum.NO.getCode())
        );
        // 获取全部部门信息
        List<SysDept> deptList = deptService.list(
                Wrappers.lambdaQuery(SysDept.class).eq(SysDept::getStatus, StatusEnum.OK.getCode()).eq(SysDept::getDeleted,DeletedEnum.NO.getCode())
        );
        // 获取性别的字典
        List<SysDict> dictList = dictService.list(
                Wrappers.lambdaQuery(SysDict.class).eq(SysDict::getParentCode, "USER-SEX").eq(SysDict::getStatus, StatusEnum.OK.getCode())
                        .eq(SysDict::getDeleted, DeletedEnum.NO.getCode())
        );
        // 组装部门map
        Map<Long, String> deptMap = deptList.stream().collect(Collectors.toMap(dept -> dept.getId(), dept -> dept.getDeptName()));
        // 组装字典map
        Map<String, String> dictMap = dictList.stream().collect(Collectors.toMap(dict -> dict.getDictCode(), dict -> dict.getDictName()));
        // 返回结果
        return userList.stream()
                .map(user -> {
                    user.setDeptName(deptMap.getOrDefault(user.getDeptId(), null));
                    user.setSexMc(dictMap.getOrDefault(String.valueOf(user.getSex()), null));
                    return user;
                }).collect(Collectors.toList());
    }
}
